/******************************************************************/
/*                                                                */
/*  Winpooch : Windows Watchdog                                   */
/*  Copyright (C) 2004-2006  Benoit Blanchon                      */
/*                                                                */
/*  This program is free software; you can redistribute it        */
/*  and/or modify it under the terms of the GNU General Public    */
/*  License as published by the Free Software Foundation; either  */
/*  version 2 of the License, or (at your option) any later       */
/*  version.                                                      */
/*                                                                */
/*  This program is distributed in the hope that it will be       */
/*  useful, but WITHOUT ANY WARRANTY; without even the implied    */
/*  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR       */
/*  PURPOSE.  See the GNU General Public License for more         */
/*  details.                                                      */
/*                                                                */
/*  You should have received a copy of the GNU General Public     */
/*  License along with this program; if not, write to the Free    */
/*  Software Foundation, Inc.,                                    */
/*  675 Mass Ave, Cambridge, MA 02139, USA.                       */
/*                                                                */
/******************************************************************/


/******************************************************************/
/* Includes                                                       */
/******************************************************************/

// module's interface
#include "ConfigWnd.h"

// standard headers
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <tchar.h>
#include <stdio.h>
#include <shlwapi.h>

// project's headers
#include "Assert.h"
#include "Config.h"
#include "FilterFile.h"
#include "Language.h"
#include "LogFile.h"
#include "ProjectInfo.h"
#include "Resources.h"
#include "Scanner.h"
#include "SpyServer.h"
#include "Strlcpy.h"
#include "Trace.h"


/******************************************************************/
/* Internal macros                                                */
/******************************************************************/

#define arraysize(a) (sizeof(a)/sizeof((a)[0]))
#define clear(a) memset(&(a),0,sizeof(a))


/******************************************************************/
/* Internal data types                                            */
/******************************************************************/

typedef struct {
  UINT		idCtrl ;
  UINT		idCfgInt ;
  UINT		idStr ;
} CONFIG_CHECKBOX ;


/******************************************************************/
/* Internal constants                                             */
/******************************************************************/

#define MAX_FILTER	128

#define WM_UPDATECONFIG	(WM_USER+10)

static CONFIG_CHECKBOX aCheckBoxes[] = {
  { IDC_DEBUG_PRIVILEGE,	CFGINT_DEBUG_PRIVILEGE },
  { IDC_SPLASH_SCREEN,		CFGINT_SPLASH_SCREEN },
  { IDC_CHECK_UPDATES,		CFGINT_CHECK_FOR_UPDATES },
  { IDC_SOUND,			CFGINT_SOUND } 
} ;

LPCTSTR g_szConfirmEraseFilters = TEXT("You will lost all existing filters.\nAre-you sure ?") ;


/******************************************************************/
/* Internal functions                                             */
/******************************************************************/

BOOL CALLBACK _ConfigWnd_DlgProc (HWND, UINT, WPARAM, LPARAM) ;

BOOL _ConfigWnd_Browse (HWND hDlg, BOOL bExport, LPTSTR szPath, UINT nMax) ;


/******************************************************************/
/* Exported function : RegisterClass                              */
/******************************************************************/

BOOL ConfigWnd_RegisterClass (HINSTANCE hInstance) 
{

  return TRUE ;
}


/******************************************************************/
/* Exported function : CreateWindow                               */
/******************************************************************/

HWND ConfigWnd_CreateWindow (HINSTANCE hInstance, HWND hwndParent)
{  
  return CreateDialog (hInstance, MAKEINTRESOURCE(DLG_CONFIG),
		       hwndParent, _ConfigWnd_DlgProc) ;
}


/******************************************************************/
/* Internal function : WndProc                                    */
/******************************************************************/

BOOL CALLBACK _ConfigWnd_DlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
  int		i ;
  UINT		nSize ;
  BOOL		bChecked ;
  TCHAR		szBuffer[1024] ;

  switch( message )
    {
    case WM_INITDIALOG:

      // set language list
      for( i=0 ; i<Language_GetLanguageCount() ; i++ )
	SendDlgItemMessage (hDlg, IDC_LANGUAGE, CB_ADDSTRING, 0,
			    (LPARAM)Language_GetLanguage(i)) ;     

    case WM_LANGUAGECHANGED:

      // add antivirus
      SendDlgItemMessage (hDlg, IDC_ANTIVIRUS, CB_RESETCONTENT, 0, 0) ; 
      SendDlgItemMessage (hDlg, IDC_ANTIVIRUS, CB_ADDSTRING, 0,
			  (LPARAM) STR_DEF(_ANTIVIRUS_NONE,TEXT("None"))) ;
      SendDlgItemMessage (hDlg, IDC_ANTIVIRUS, CB_ADDSTRING, 0,
			  (LPARAM) STR_DEF(_ANTIVIRUS_CLAMWIN,TEXT("ClamWin"))) ;
      SendDlgItemMessage (hDlg, IDC_ANTIVIRUS, CB_ADDSTRING, 0,
			  (LPARAM) STR_DEF(_ANTIVIRUS_KASPERSKY_WS,TEXT("Kaspersky antivirus for Workstation"))) ;

      // set language dependant strings
      if( Language_IsLoaded() )
	{
	  SendDlgItemMessage (hDlg, IDC_LANGUAGE, CB_SELECTSTRING, 0,
			      (LPARAM)STR(_LANGUAGE_NAME_IN_ENGLISH)) ;   
	  SetDlgItemText (hDlg, IDT_CONFIGURATION, STR(_CONFIGURATION)) ;   
	  SetDlgItemText (hDlg, IDT_ANTIVIRUS, STR(_ANTIVIRUS)) ;
	  SetDlgItemText (hDlg, IDT_LANGUAGE, STR(_LANGUAGE)) ;
	  SetDlgItemText (hDlg, IDC_DEBUG_PRIVILEGE, STR(_USE_DEBUG_PRIVILEGE)) ;
	  SetDlgItemText (hDlg, IDC_SPLASH_SCREEN, STR(_ENABLE_SPLASH_SCREEN)) ;
	  SetDlgItemText (hDlg, IDC_CHECK_UPDATES, STR(_CHECK_FOR_UPDATES)) ;
	  SetDlgItemText (hDlg, IDC_SOUND, STR(_ENABLE_SOUND)) ;
	  SetDlgItemText (hDlg, IDT_MAX_LOG_SIZE, STR(_MAX_LOG_FILE_SIZE)) ;
	  SetDlgItemText (hDlg, IDT_KILOBYTES, STR(_KILOBYTES)) ;
	  SetDlgItemText (hDlg, IDC_APPLY, STR(_APPLY_CONFIGURATION)) ;
	  SetDlgItemText (hDlg, IDT_FILTERS, STR(_FILTERS)) ;
	  SetDlgItemText (hDlg, IDC_IMPORT, STR(_IMPORT)) ;
	  SetDlgItemText (hDlg, IDC_EXPORT, STR(_EXPORT)) ;
	  SetDlgItemText (hDlg, IDC_RESET, STR(_RESET)) ;
	}

    case WM_UPDATECONFIG:

      // antivirus
      SendDlgItemMessage (hDlg, IDC_ANTIVIRUS, CB_SETCURSEL, 
			  Scanner_GetScanner(), 0) ;

      // check boxes
      for( i=0 ; i<arraysize(aCheckBoxes) ; i++ )
	CheckDlgButton (hDlg, aCheckBoxes[i].idCtrl, 
			Config_GetInteger(aCheckBoxes[i].idCfgInt)
			? BST_CHECKED : BST_UNCHECKED) ;      

      // max log size
      SetDlgItemInt (hDlg, IDC_MAX_LOG_SIZE,
		     Config_GetInteger(CFGINT_MAX_LOG_SIZE)>>10,
		     FALSE) ;
      
      EnableWindow (GetDlgItem(hDlg,IDC_APPLY), FALSE) ;

      return TRUE ;

    case WM_COMMAND:

     switch( wParam )
	{
	case MAKELONG(IDC_DEBUG_PRIVILEGE,BN_CLICKED):
	case MAKELONG(IDC_SPLASH_SCREEN,BN_CLICKED): 
	case MAKELONG(IDC_CHECK_UPDATES,BN_CLICKED): 
	case MAKELONG(IDC_SOUND,BN_CLICKED): 
	case MAKELONG(IDC_MAX_LOG_SIZE,EN_CHANGE): 
	case MAKELONG(IDC_LANGUAGE,CBN_SELCHANGE): 
	case MAKELONG(IDC_ANTIVIRUS,CBN_SELCHANGE): 
	  EnableWindow (GetDlgItem(hDlg,IDC_APPLY), TRUE) ;
	  return TRUE ;

	case MAKELONG(IDC_APPLY,BN_CLICKED): 

	  // for each check box
	  for( i=0 ; i<arraysize(aCheckBoxes) ; i++ ) {
	    bChecked = IsDlgButtonChecked (hDlg, aCheckBoxes[i].idCtrl) == BST_CHECKED ;
	    Config_SetInteger (aCheckBoxes[i].idCfgInt, bChecked) ;
	  }

	  // max log size
	  nSize = 1024 * GetDlgItemInt (hDlg, IDC_MAX_LOG_SIZE, NULL, FALSE) ;	  
	  Config_SetInteger (CFGINT_MAX_LOG_SIZE, nSize) ;	 

	  // antivirus
	  if( ! Scanner_SetScanner(SendDlgItemMessage(hDlg,IDC_ANTIVIRUS,CB_GETCURSEL,0,0)) )
	    MessageBox (hDlg, STR_DEF(_ANTIVIRUS_NOT_INSTALLED,
				      TEXT("The antivirus you selected isn't installed")),
			TEXT(APPLICATION_NAME), MB_ICONERROR) ;

	  // language
	  GetDlgItemText (hDlg, IDC_LANGUAGE, szBuffer, 64) ;
	  Language_LoadByName (szBuffer) ;
	  
	  LogFile_ReloadConfig () ;
	  SpySrv_ReloadConfig () ;

	  SendMessage (hDlg, WM_UPDATECONFIG, 0, 0) ;

	  return TRUE ; // IDC_APPLY

	case MAKELONG(IDC_EXPORT,BN_CLICKED): //    ======== 'Export' button clicked ========
	  {
	    TCHAR szFileName[64] ;
	    int i ;
	    
	    if( _ConfigWnd_Browse (hDlg, TRUE, szBuffer, MAX_PATH) )
	      {
		if( ! FilterFile_Write (szBuffer, SpySrv_GetFilterSet()) )
		  {
		    
		    _tcslcpy (szFileName, PathFindFileName(szBuffer), 64) ;
		    
		    i = wsprintf (szBuffer, STR_DEF(_ERROR_WRITING_FILE_S,
						    TEXT("Error writing file \"%s\"")), szFileName) ;
		    
		    wsprintf (szBuffer+i, TEXT("\r\n%s"), FilterFile_GetErrorString()) ;
		    
		    MessageBox (hDlg, szBuffer, NULL, MB_ICONERROR) ;
		  }
	      }
	  }
	  return TRUE ;  //    ======== 'Export' button clicked ========

	case MAKELONG(IDC_IMPORT,BN_CLICKED): //    ======== 'Import' button clicked ========
	  {
	    HFILTERSET	hFilterSet ;
	    TCHAR	szFileName[64] ;
	    int		i ;
	    
	    if( _ConfigWnd_Browse (hDlg, FALSE, szBuffer, MAX_PATH) )
	      {		
		hFilterSet = FilterFile_Read (szBuffer) ;
		
		if( ! hFilterSet )
		  {		    
		    _tcslcpy (szFileName, PathFindFileName(szBuffer), 64) ;
		    
		    i = wsprintf (szBuffer, STR_DEF(_ERROR_READING_FILE_S,
						    TEXT("Error reading file \"%s\"")), szFileName) ;
		    
		    wsprintf (szBuffer+i, TEXT("\r\n%s"), FilterFile_GetErrorString()) ;
		    
		    MessageBox (hDlg, szBuffer, NULL, MB_ICONERROR) ;
		  }
		else
		  {
		    i = MessageBox(hDlg, 
				   STR_DEF(_CONFIRM_ERASE_FILTERS, g_szConfirmEraseFilters),
				   TEXT(APPLICATION_NAME),
				   MB_ICONWARNING|MB_YESNO) ;

		    if( i==IDYES )
		      SpySrv_SetFilterSet (hFilterSet) ;
		    else
		      FilterSet_Destroy (hFilterSet) ;
		  }
	      }	    
	  }
	  return TRUE ; //    ======== 'Import' button clicked ========

	case MAKELONG(IDC_RESET,BN_CLICKED): //    ======== 'Reset' button clicked ========
	  {
	    HFILTERSET	hFilterSet ;
	    int		i ;
	    
	    hFilterSet = FilterSet_Create (64) ;
	    
	    if( hFilterSet )
	      {	
		FilterSet_InitDefaultFilter (hFilterSet) ;
	    
		i = MessageBox(hDlg, 
			       STR_DEF(_CONFIRM_ERASE_FILTERS, g_szConfirmEraseFilters),
			       TEXT(APPLICATION_NAME),
			       MB_ICONWARNING|MB_YESNO) ;
		
		if( i==IDYES )
		  SpySrv_SetFilterSet (hFilterSet) ;
		else
		  FilterSet_Destroy (hFilterSet) ;
	      }	  	    
	  }
	  return TRUE ; //    ======== 'Reset' button clicked ========
	}

      return FALSE ;

    }

  return FALSE ;
}


/******************************************************************/
/* Internal function : Browse                                     */
/******************************************************************/

BOOL _ConfigWnd_Browse (HWND hDlg, BOOL bExport, LPTSTR szPath, UINT nMax)
{
  TCHAR szFilter[MAX_FILTER] ;
  INT   iPos ;  
  
  OPENFILENAME ofn = {
    .lStructSize = sizeof(OPENFILENAME),
    .hwndOwner   = hDlg,
    .nMaxFile    = nMax,
    .lpstrFile   = szPath,
    .lpstrFilter = szFilter,
    .lpstrDefExt = TEXT("wpf"),
  } ;
  
  szPath[0] = 0 ;

  if( bExport )
    ofn.Flags = OFN_PATHMUSTEXIST ;
  else
    ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY ;
  
  iPos = 0 ;

  iPos += 1 + _sntprintf (szFilter+iPos, MAX_FILTER-iPos, TEXT("%s (*.wpf)"),
			  STR_DEF(_FILTER_FILES,TEXT("Winpooch filters"))) ;
  iPos += 1 + _sntprintf (szFilter+iPos, MAX_FILTER-iPos, TEXT("*.wpf")) ;

  iPos += 1 + _sntprintf (szFilter+iPos, MAX_FILTER-iPos, TEXT("%s (*.*)"),
			  STR_DEF(_ALL_FILES,TEXT("All files"))) ;
  iPos += 1 + _sntprintf (szFilter+iPos, MAX_FILTER-iPos, TEXT("*.*")) ;

  szFilter[iPos] = 0 ;
  
  if( bExport ) return GetSaveFileName (&ofn) ;
  return GetOpenFileName (&ofn) ;
}
